| Conditions | 17 |
| Paths | 6144 |
| Total Lines | 154 |
| Code Lines | 92 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 1 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like eventsource.js ➔ ... ➔ connect often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | var original = require('original') |
||
| 69 | function connect () { |
||
| 70 | var options = parse(url) |
||
| 71 | var isSecure = options.protocol === 'https:' |
||
| 72 | options.headers = { 'Cache-Control': 'no-cache', 'Accept': 'text/event-stream' } |
||
| 73 | if (lastEventId) options.headers['Last-Event-ID'] = lastEventId |
||
| 74 | if (eventSourceInitDict && eventSourceInitDict.headers) { |
||
| 75 | for (var i in eventSourceInitDict.headers) { |
||
| 76 | var header = eventSourceInitDict.headers[i] |
||
| 77 | if (header) { |
||
| 78 | options.headers[i] = header |
||
| 79 | } |
||
| 80 | } |
||
| 81 | } |
||
| 82 | |||
| 83 | // Legacy: this should be specified as `eventSourceInitDict.https.rejectUnauthorized`, |
||
| 84 | // but for now exists as a backwards-compatibility layer |
||
| 85 | options.rejectUnauthorized = !(eventSourceInitDict && !eventSourceInitDict.rejectUnauthorized) |
||
| 86 | |||
| 87 | // If specify http proxy, make the request to sent to the proxy server, |
||
| 88 | // and include the original url in path and Host headers |
||
| 89 | var useProxy = eventSourceInitDict && eventSourceInitDict.proxy |
||
| 90 | if (useProxy) { |
||
| 91 | var proxy = parse(eventSourceInitDict.proxy) |
||
| 92 | isSecure = proxy.protocol === 'https:' |
||
| 93 | |||
| 94 | options.protocol = isSecure ? 'https:' : 'http:' |
||
| 95 | options.path = url |
||
| 96 | options.headers.Host = options.host |
||
| 97 | options.hostname = proxy.hostname |
||
| 98 | options.host = proxy.host |
||
| 99 | options.port = proxy.port |
||
| 100 | } |
||
| 101 | |||
| 102 | // If https options are specified, merge them into the request options |
||
| 103 | if (eventSourceInitDict && eventSourceInitDict.https) { |
||
| 104 | for (var optName in eventSourceInitDict.https) { |
||
| 105 | if (httpsOptions.indexOf(optName) === -1) { |
||
| 106 | continue |
||
| 107 | } |
||
| 108 | |||
| 109 | var option = eventSourceInitDict.https[optName] |
||
| 110 | if (option !== undefined) { |
||
| 111 | options[optName] = option |
||
| 112 | } |
||
| 113 | } |
||
| 114 | } |
||
| 115 | |||
| 116 | // Pass this on to the XHR |
||
| 117 | if (eventSourceInitDict && eventSourceInitDict.withCredentials !== undefined) { |
||
| 118 | options.withCredentials = eventSourceInitDict.withCredentials |
||
| 119 | } |
||
| 120 | |||
| 121 | req = (isSecure ? https : http).request(options, function (res) { |
||
| 122 | // Handle HTTP errors |
||
| 123 | if (res.statusCode === 500 || res.statusCode === 502 || res.statusCode === 503 || res.statusCode === 504) { |
||
| 124 | _emit('error', new Event('error', {status: res.statusCode})) |
||
| 125 | onConnectionClosed() |
||
| 126 | return |
||
| 127 | } |
||
| 128 | |||
| 129 | // Handle HTTP redirects |
||
| 130 | if (res.statusCode === 301 || res.statusCode === 307) { |
||
| 131 | if (!res.headers.location) { |
||
| 132 | // Server sent redirect response without Location header. |
||
| 133 | _emit('error', new Event('error', {status: res.statusCode})) |
||
| 134 | return |
||
| 135 | } |
||
| 136 | if (res.statusCode === 307) reconnectUrl = url |
||
| 137 | url = res.headers.location |
||
| 138 | process.nextTick(connect) |
||
| 139 | return |
||
| 140 | } |
||
| 141 | |||
| 142 | if (res.statusCode !== 200) { |
||
| 143 | _emit('error', new Event('error', {status: res.statusCode})) |
||
| 144 | return self.close() |
||
| 145 | } |
||
| 146 | |||
| 147 | // protect against multiple connects |
||
| 148 | //https://github.com/tigertext/eventsource/commit/ca8a6e0ca0db10c23ba7bf2b7f8affaa23d7a265 |
||
| 149 | if (readyState === EventSource.OPEN) { |
||
| 150 | return; |
||
| 151 | } |
||
| 152 | |||
| 153 | readyState = EventSource.OPEN |
||
| 154 | res.on('close', function () { |
||
| 155 | res.removeAllListeners('close') |
||
| 156 | res.removeAllListeners('end') |
||
| 157 | onConnectionClosed() |
||
| 158 | }) |
||
| 159 | |||
| 160 | res.on('end', function () { |
||
| 161 | res.removeAllListeners('close') |
||
| 162 | res.removeAllListeners('end') |
||
| 163 | onConnectionClosed() |
||
| 164 | }) |
||
| 165 | _emit('open', new Event('open')) |
||
| 166 | |||
| 167 | // text/event-stream parser adapted from webkit's |
||
| 168 | // Source/WebCore/page/EventSource.cpp |
||
| 169 | var buf = '' |
||
| 170 | res.on('data', function (chunk) { |
||
| 171 | buf += chunk |
||
| 172 | |||
| 173 | var pos = 0 |
||
| 174 | var length = buf.length |
||
| 175 | |||
| 176 | while (pos < length) { |
||
| 177 | if (discardTrailingNewline) { |
||
| 178 | if (buf[pos] === '\n') { |
||
| 179 | ++pos |
||
| 180 | } |
||
| 181 | discardTrailingNewline = false |
||
| 182 | } |
||
| 183 | |||
| 184 | var lineLength = -1 |
||
| 185 | var fieldLength = -1 |
||
| 186 | var c |
||
| 187 | |||
| 188 | for (var i = pos; lineLength < 0 && i < length; ++i) { |
||
| 189 | c = buf[i] |
||
| 190 | if (c === ':') { |
||
| 191 | if (fieldLength < 0) { |
||
| 192 | fieldLength = i - pos |
||
| 193 | } |
||
| 194 | } else if (c === '\r') { |
||
| 195 | discardTrailingNewline = true |
||
| 196 | lineLength = i - pos |
||
| 197 | } else if (c === '\n') { |
||
| 198 | lineLength = i - pos |
||
| 199 | } |
||
| 200 | } |
||
| 201 | |||
| 202 | if (lineLength < 0) { |
||
| 203 | break |
||
| 204 | } |
||
| 205 | |||
| 206 | parseEventStreamLine(buf, pos, fieldLength, lineLength) |
||
| 207 | |||
| 208 | pos += lineLength + 1 |
||
| 209 | } |
||
| 210 | |||
| 211 | if (pos === length) { |
||
| 212 | buf = '' |
||
| 213 | } else if (pos > 0) { |
||
| 214 | buf = buf.slice(pos) |
||
| 215 | } |
||
| 216 | }) |
||
| 217 | }) |
||
| 218 | |||
| 219 | req.on('error', onConnectionClosed) |
||
| 220 | if (req.setNoDelay) req.setNoDelay(true) |
||
| 221 | req.end() |
||
| 222 | } |
||
| 223 | |||
| 401 |